from PIL import Image
import numpy as np


def read_img(filename):
    image = Image.open(filename)
    return image


def pca(mat,dim):
    """
    此函数处理一个颜色通道矩阵的pca主成分（协方差矩阵中特征值最大的特征的选取）
    :param mat: 输入矩阵，单颜色通道
    :param dim: pca主成分选取的个数
    :return: 1、被选中的特征向量乘以均值所构成的矩阵 2、pca降维后重构出的矩阵
    """
    mean_val = np.mean(mat,axis=0)
    remove_mean = mat-mean_val
    cov_mat = np.cov(remove_mean,rowvar=0)
    eig_val,eig_vec = np.linalg.eig(np.mat(cov_mat))
    eig_val_index = np.argsort(eig_val)
    eig_val_index = eig_val_index[:-dim-1:-1]
    red_eig_vector = eig_vec[:,eig_val_index]
    low_dim_mat = remove_mean * red_eig_vector
    recon_mat = (low_dim_mat*red_eig_vector.T)+mean_val
    return low_dim_mat,recon_mat

# def multi_channel_pca(mat,dim):
#     """
#
#     :param mat:
#     :param dim:
#     :return:
#     """
#     channel_num = mat.shape()[2]
#     for i in range(channel_num):

if __name__=='__main__':
    img = read_img('lena.jpg')
    mat = np.asarray(img)
    # 取RGB第一个通道，转化为单色图片
    mat = mat[:,:,0]
    print(mat)
    img_from_mat = Image.fromarray(mat)
    low,recon = pca(mat,100)
    recon_float = np.matrix(recon,dtype='float32')
    Image.fromarray(recon_float).show()
    img_from_mat.show()